package com.network.topo.snmp;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;

import org.snmp4j.CommunityTarget;
import org.snmp4j.Target;
import org.snmp4j.UserTarget;
import org.snmp4j.mp.SnmpConstants;
import org.snmp4j.smi.Address;
import org.snmp4j.smi.OctetString;

import com.network.util.snmp4j.SnmpGet;
import com.network.util.snmp4j.SnmpGetResultSet;

public final class BgpPeerTable extends AbstractXxxTable
{
	private static ArrayList<String> oidList = null;
	private HashMap<Object, RowData> objDataMap = new HashMap<Object, RowData>();
	private HashMap<Object, RowData> indexDataMap = new HashMap<Object, RowData>();
	private SnmpGet snmp4j = null;
	private int rowCount = 0;
	private Target target = null;

	private BgpPeerTable(SnmpGetResultSet resultSet)
	{
		this.resultSet = resultSet;
		if (this.resultSet != null)
		{
			rowCount = this.resultSet.getRowCount();
			for (int i = 0; i < rowCount; i++)
			{
				RowData rowData = new RowData();
				int oidIndex = 0;
				
				rowData.bgpPeerIdentifier = getValue(getOidList().get(oidIndex++), i);
				rowData.bgpPeerState = str2int(getValue(getOidList().get(oidIndex++), i));
				rowData.bgpPeerLocalAddr = getValue(getOidList().get(oidIndex++), i);
				rowData.bgpPeerLocalPort = str2int(getValue(getOidList().get(oidIndex++), i));
				rowData.bgpPeerRemoteAddr = getValue(getOidList().get(oidIndex++), i);
				rowData.bgpPeerRemotePort = str2int(getValue(getOidList().get(oidIndex++), i));
				
				indexDataMap.put(i, rowData);
			}
		}
	}

	private RowData getRowData(int row)
	{
		RowData rowData = new RowData();
		
		rowData.bgpPeerIdentifier = getBgpPeerIdentifier(row, true);
		rowData.bgpPeerState = getBgpPeerState(row, true);
		rowData.bgpPeerLocalAddr = getBgpPeerLocalAddr(row, true);
		rowData.bgpPeerLocalPort = getBgpPeerLocalPort(row, true);
		rowData.bgpPeerRemoteAddr = getBgpPeerRemoteAddr(row, true);
		rowData.bgpPeerRemotePort = getBgpPeerRemotePort(row, true);
		
		return rowData;
	}

	public static BgpPeerTable getInstance(SnmpGet snmpGet, Target target)
	{
		SnmpGetResultSet sgrs = null;
		BgpPeerTable instance = null;
		try
		{
			sgrs = snmpGet.query(getOidList(), target);
		}
		catch (IOException e)
		{
			e.printStackTrace();
		}
		if (sgrs != null && sgrs.next() == true)
		{
			instance = new BgpPeerTable(sgrs);
		}

		return instance;
	}

	public static synchronized ArrayList<String> getOidList()
	{
		if (oidList == null)
		{
			oidList = new ArrayList<String>();
			oidList.add("1.3.6.1.2.1.15.3.1.1");
			oidList.add("1.3.6.1.2.1.15.3.1.2");
			oidList.add("1.3.6.1.2.1.15.3.1.5");
			oidList.add("1.3.6.1.2.1.15.3.1.6");
			oidList.add("1.3.6.1.2.1.15.3.1.7");
			oidList.add("1.3.6.1.2.1.15.3.1.8");
		}
		return oidList;
	}
	
	protected static Target newTarget(SnmpGet snmpGet, String ipAddr, ArrayList<String> communityList, int snmpVersion) throws IOException
	{
		Target target = null;
		Address addr = SnmpGet.parserAddress("udp:" + ipAddr);

		if (addr == null)
		{
			return null;
		}
		if (snmpVersion == SnmpConstants.version1)
		{
			target = new CommunityTarget();
			target.setVersion(SnmpConstants.version1);
		}
		else if (snmpVersion == SnmpConstants.version2c)
		{
			target = new CommunityTarget();
			target.setVersion(SnmpConstants.version2c);
		}
		else if (snmpVersion == SnmpConstants.version3)
		{
			target = new UserTarget();
			target.setVersion(SnmpConstants.version3);
		}
		target.setAddress(addr);
		boolean isFindCommunity = false;
		ArrayList<String> oidList = new ArrayList<String>();
		oidList.add(SysInfo.getOidList().get(1));
		for (String community : communityList)
		{
			if (target instanceof CommunityTarget)
			{
				CommunityTarget objTemp = (CommunityTarget) target;
				objTemp.setCommunity(new OctetString(community));
			}
			if (snmpGet.query(oidList, target) != null)
			{
				isFindCommunity = true;
				break;
			}
		}
		if (isFindCommunity == false)
		{
			target = null;
			addr = null;

		}
		return target;
	}

	public String getBgpPeerIdentifier(Object obj, boolean useIndex)
	{
		String rtnValue = "127.0.0.1";
		RowData rowData = null;
		if (useIndex)
		{
			rowData = indexDataMap.get(obj);
		}
		else
		{
			rowData = objDataMap.get(obj);
		}
		if (rowData != null)
		{
			rtnValue = rowData.getBgpPeerIdentifier();
		}
		return rtnValue;
	}

	public String getBgpPeerLocalAddr(Object obj, boolean useIndex)
	{
		String rtnValue = "127.0.0.1";
		RowData rowData = null;
		if (useIndex)
		{
			rowData = indexDataMap.get(obj);
		}
		else
		{
			rowData = objDataMap.get(obj);
		}
		if (rowData != null)
		{
			rtnValue = rowData.getBgpPeerLocalAddr();
		}
		return rtnValue;
	}
	
	public String getBgpPeerRemoteAddr(Object obj, boolean useIndex)
	{
		String rtnValue = "127.0.0.1";
		RowData rowData = null;
		if (useIndex)
		{
			rowData = indexDataMap.get(obj);
		}
		else
		{
			rowData = objDataMap.get(obj);
		}
		if (rowData != null)
		{
			rtnValue = rowData.getBgpPeerRemoteAddr();
		}
		return rtnValue;
	}
	
	public int getBgpPeerState(Object obj, boolean useIndex)
	{
		int rtnValue = 0;
		RowData rowData = null;
		if (useIndex)
		{
			rowData = indexDataMap.get(obj);
		}
		else
		{
			rowData = objDataMap.get(obj);
		}
		if (rowData != null)
		{
			rtnValue = rowData.getBgpPeerState();
		}
		return rtnValue;
	}

	public int getBgpPeerLocalPort(Object obj, boolean useIndex)
	{
		int rtnValue = 0;
		RowData rowData = null;
		if (useIndex)
		{
			rowData = indexDataMap.get(obj);
		}
		else
		{
			rowData = objDataMap.get(obj);
		}
		if (rowData != null)
		{
			rtnValue = rowData.getBgpPeerLocalPort();
		}
		return rtnValue;
	}
	
	public int getBgpPeerRemotePort(Object obj, boolean useIndex)
	{
		int rtnValue = 0;
		RowData rowData = null;
		if (useIndex)
		{
			rowData = indexDataMap.get(obj);
		}
		else
		{
			rowData = objDataMap.get(obj);
		}
		if (rowData != null)
		{
			rtnValue = rowData.getBgpPeerRemotePort();
		}
		return rtnValue;
	}
	
	public class RowData
	{
		private String bgpPeerIdentifier = "";	
		private int bgpPeerState = 0;
		private String bgpPeerLocalAddr = "";
		private int bgpPeerLocalPort = 0;
		private String bgpPeerRemoteAddr = "";
		private int bgpPeerRemotePort = 0;

		public String getBgpPeerIdentifier() {
			return bgpPeerIdentifier;
		}

		public void setBgpPeerIdentifier(String bgpPeerIdentifier) {
			this.bgpPeerIdentifier = bgpPeerIdentifier;
			if (this.bgpPeerIdentifier == null || this.bgpPeerIdentifier.split("[.]").length != 4)
			{
				this.bgpPeerIdentifier = "127.0.0.1";
			}
		}

		public String getBgpPeerLocalAddr() {
			return bgpPeerLocalAddr;
		}

		public void setBgpPeerLocalAddr(String bgpPeerLocalAddr) {
			this.bgpPeerLocalAddr = bgpPeerLocalAddr;
			if (this.bgpPeerLocalAddr == null || this.bgpPeerLocalAddr.split("[.]").length != 4)
			{
				this.bgpPeerLocalAddr = "127.0.0.1";
			}
		}

		public int getBgpPeerLocalPort() {
			return bgpPeerLocalPort;
		}

		public void setBgpPeerLocalPort(int bgpPeerLocalPort) {
			this.bgpPeerLocalPort = bgpPeerLocalPort;
		}

		public String getBgpPeerRemoteAddr() {
			return bgpPeerRemoteAddr;
		}

		public void setBgpPeerRemoteAddr(String bgpPeerRemoteAddr) {
			this.bgpPeerRemoteAddr = bgpPeerRemoteAddr;
			if (this.bgpPeerRemoteAddr == null || this.bgpPeerRemoteAddr.split("[.]").length != 4)
			{
				this.bgpPeerRemoteAddr = "127.0.0.1";
			}
		}

		public int getBgpPeerRemotePort() {
			return bgpPeerRemotePort;
		}

		public void setBgpPeerRemotePort(int bgpPeerRemotePort) {
			this.bgpPeerRemotePort = bgpPeerRemotePort;
		}

		public int getBgpPeerState() {
			return bgpPeerState;
		}

		public void setBgpPeerState(int bgpPeerState) {
			this.bgpPeerState = bgpPeerState;
		}

	}

	public int getRowCount()
	{
		return rowCount;
	}

	public void setRowCount(int rowCount)
	{
		this.rowCount = rowCount;
	}

	public Target getTarget() {
		return target;
	}

	public void setTarget(Target target) {
		this.target = target;
	}

	public SnmpGet getSnmp4j() {
		return snmp4j;
	}

	public void setSnmp4j(SnmpGet snmp4j) {
		this.snmp4j = snmp4j;
	}
}
